package edu.cicese.alz.reports;

import edu.cicese.alz.SwingComponent;
import edu.cicese.alz.util.Utilities;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.DateTickMarkPosition;
import org.jfree.chart.axis.SegmentedTimeline;
import org.jfree.chart.axis.SymbolAxis;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.LookupPaintScale;
import org.jfree.chart.renderer.xy.XYBlockRenderer;
import org.jfree.chart.title.PaintScaleLegend;
import org.jfree.data.xy.DefaultXYZDataset;
import org.jfree.data.xy.XYZDataset;
import org.jfree.ui.RectangleAnchor;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.RectangleInsets;

import java.awt.Color;
import java.awt.Dimension;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.TimeZone;

/**
 * Created by: Eduardo Quintana Contreras
 * Date: 8/08/12
 * Time: 05:52 PM
 */
public class FrameBlock extends SwingComponent {
	private int userID;
	protected String title;
	private int days;
	private long startTime;
	private boolean saveChart = false;
	private String outputDir;

	protected LookupPaintScale paintScale;
	protected SymbolAxis symbolAxis;

	public FrameBlock(int userID, long startTime) {
		this.userID = userID;
		this.startTime = startTime;
	}

	public void setOutputDir(String outputDir) {
		this.saveChart = true;
		this.outputDir = outputDir;
	}

	public void plotData(double[][] values, int days) {
		DefaultXYZDataset xyzDataset = new DefaultXYZDataset();
		xyzDataset.addSeries("Series 1", values);

		this.days = days;
		ChartPanel chartPanel = new ChartPanel(createChart(xyzDataset));
		chartPanel.setPreferredSize(new Dimension(1190, 130 + (days * 21)));
		setContentPane(chartPanel);
	}

	private JFreeChart createChart(XYZDataset xyzDataset) {
		DateAxis yAxis = new DateAxis("Date");
		SimpleDateFormat sdfDay = new SimpleDateFormat("yyyy/MM/dd");
		yAxis.setTickMarkPosition(DateTickMarkPosition.START);
		yAxis.setDateFormatOverride(sdfDay);
		yAxis.setLowerMargin(0);
		yAxis.setUpperMargin(0);
		yAxis.setInverted(true);

		DateAxis xAxis = new DateAxis("Date");
		SimpleDateFormat sdfHour = new SimpleDateFormat("HH:mm");
		xAxis.setDateFormatOverride(sdfHour);
		sdfHour.setTimeZone(TimeZone.getTimeZone("GMT"));
		xAxis.setLowerMargin(0);
		xAxis.setUpperMargin(0);

		SegmentedTimeline timeLine = new SegmentedTimeline(86400000, 24, 0);
		timeLine.setStartTime(startTime);
		xAxis.setTimeline(timeLine);

		XYBlockRenderer xyBlockRenderer = new XYBlockRenderer();
		xyBlockRenderer.setBlockWidth(86400000.0D);
		xyBlockRenderer.setBlockHeight(60000.0D);
		xyBlockRenderer.setBlockAnchor(RectangleAnchor.BOTTOM_LEFT);

		XYPlot xyPlot = new XYPlot(xyzDataset, yAxis, xAxis, xyBlockRenderer);
		xyPlot.setRangeGridlinesVisible(true);
		xyPlot.setOrientation(PlotOrientation.HORIZONTAL);
		xyPlot.setBackgroundPaint(Color.WHITE);
		xyPlot.setRangeGridlinePaint(Color.WHITE);
		xyPlot.setAxisOffset(new RectangleInsets(5, 5, 5, 5));

		JFreeChart chart = new JFreeChart(title, xyPlot);
		chart.removeLegend();
		chart.setBackgroundPaint(Color.WHITE);

		xyBlockRenderer.setPaintScale(paintScale);

		symbolAxis.setPlot(new PiePlot());
		symbolAxis.setGridBandsVisible(false);

		PaintScaleLegend paintScaleLegend = new PaintScaleLegend(paintScale, symbolAxis);
		paintScaleLegend.setMargin(new RectangleInsets(3, 10, 3, 10));
		paintScaleLegend.setPosition(RectangleEdge.BOTTOM);
		paintScaleLegend.setAxisOffset(5);
		chart.addSubtitle(paintScaleLegend);

		ChartUtilities.applyCurrentTheme(chart);

		if (saveChart) {
			try {
				ChartUtilities.saveChartAsPNG(new File(outputDir + Utilities.addZeros(userID, 2) + ".png"), chart, 1190, 130 + (days * 21));
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		return chart;
	}
}
